package Towers;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;

import particulas.Faisca;

import Main.GamePanel;
import Screens.TelaJogo;
import Screens.TelaTreinamento;
import Utils.Constantes;
import Utils.Utilidades;

public class Tower {
	public int x;
	public int y; 
	public int width;
	public int height;
	// atributos 
	public float life;
	public float lifeMax;
	public int range;
	public float damage;
	public int custo;
	// Definir para as torres
	public int cadencia = 1200;
	// variaveis para desenho
	public BufferedImage imagemDemonstracao;
	public BufferedImage imagemNoCenario;
	public boolean selecionada;
	public boolean selecionadoNoCenario;
	public Color cor;
	public boolean fixada;
	public boolean visible;
	public int posXInicial;
	public int posYInicial;
	public int tipoDaTorre;
	public int timer = 0;	
	public boolean viva;
	double ang;
	// bruno
	public boolean isbuff;
	public float bonusAtaque;
	public float bonusRange;
	public int contadorRecoverLife;
	public int delayRecoverLife = 5000;
	FX_Tiro  efeitoTiro;
	FX_Buff efeitoBuff;



	public Tower(int posX, int posY, int Width, int Height, BufferedImage img, BufferedImage img2) {
		// TODO Auto-generated constructor stub

		x = posX;
		y = posY;
		width = Width;
		height = Height;
		imagemNoCenario = img;
		imagemDemonstracao = img2;
		selecionada = false;
		cor = Color.BLUE;		
		fixada = false;
		visible = true;
		selecionadoNoCenario = false;
		range = 50;
		posXInicial = posX;
		posYInicial = posY;
		viva = true;
		 bonusAtaque =0;
		 bonusRange =0;
		



	}

	public Tower(int posX, int posY, int width2, int height2, String fileNameMapa, String fileNamePainel) {
		// TODO Auto-generated constructor stub
		x = posX;
		y = posY;
		width = width2;
		height = height2;
		imagemNoCenario = Utilidades.LoadImage(fileNameMapa);
		imagemDemonstracao = Utilidades.LoadImage(fileNamePainel);
		selecionada = false;
		cor = Color.BLUE;		
		fixada = false;
		selecionadoNoCenario = false;
		visible = true;
		range = 50;
		posXInicial = posX;
		posYInicial = posY;
		viva = true;
		 bonusAtaque =0;
		 bonusRange =0;
	}
	
	public Tower(int posX, int posY, int width2, int height2, int numImagem) {
		// TODO Auto-generated constructor stub
		x = posX;
		y = posY;
		width = width2;
		height = height2;
		imagemNoCenario = Utilidades.LoadImage("/torres/m"+numImagem+".png");
		imagemDemonstracao = Utilidades.LoadImage("/torres/"+numImagem+".png");
		selecionada = false;
		cor = Color.BLUE;		
		fixada = false;
		visible = true;
		selecionadoNoCenario = false;
		range = 50;
		posXInicial = posX;
		posYInicial = posY;
		viva = true;
		constroiTorre(numImagem);
		 bonusAtaque =0;
		 bonusRange =0;
	}

	public void constroiTorre(int tipo){
		tipoDaTorre = tipo;
		// TODO
		
		switch(tipo){
		
		case 0:
			damage = 2;
			lifeMax =life = 10;
			range = 55;
			custo= 10;
			isbuff = false;
			cadencia = 700;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.png");
			break;
		
		case 1:
			damage = 2;
			lifeMax =life = 20;
			range = 65;
			custo= 40;
			isbuff = false;
			cadencia = 1000;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.png");
			break;
		
		case 2:
			damage = 10;
			lifeMax =life = 10;
			range = 55;
			custo= 50;
			isbuff = false;
			cadencia = 800;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.png");
			break;
		
		case 3:
			damage = 10;
			lifeMax =life = 20;
			range = 65;
			custo= 75;
			isbuff = false;
			cadencia = 900;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.png");
			break;
		
		case 4:
			damage = 18;
			lifeMax =life = 23;
			range = 85;
			custo= 100;
			isbuff = false;
			cadencia = 1200;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.png");
			break;
		
		case 5:
			damage = 20;
			lifeMax =life = 46;
			range = 100;
			custo= 135;
			isbuff = false;
			cadencia = 500;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro2.png");
			break;
	
		case 6:
			damage = 30;
			lifeMax =life = 50;
			range = 90;
			custo= 175;
			isbuff = false;
			cadencia = 1500;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.png");
			break;
		
		case 7:
			damage = 40;
			lifeMax =life = 30;
			range = 90;
			custo= 190;
			isbuff = false;
			cadencia = 1300;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.png");
			break;
		
		case 8:
			damage = 40;
			lifeMax =life = 30;
			range = 120;
			custo= 220;
			isbuff = false;
			cadencia = 900;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro3.png");
			break;
		
		case 9:
			damage = 50;
			lifeMax =life = 50;
			range = 120;
			custo= 250;
			isbuff = false;
			cadencia = 700;
			efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro4.png");
			break;
		
		case 10:
			damage = 0;
			lifeMax =life = 10;
			range = 85;
			custo= 50;
			isbuff = true;
			cadencia = 1500;
			//efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.PNG");
			efeitoBuff = new FX_Buff(x, y, 170, 170, cadencia, "/tiros/buff1.png");
			break;
		

		case 11:
			damage = 0;
			lifeMax =life = 40;
			range = 55;
			custo= 80;
			isbuff = true;
			cadencia = 1500;
			//efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.PNG");
			efeitoBuff = new FX_Buff(x, y, 110, 110, delayRecoverLife/2, "/tiros/buff2.png");
			break;
		
		case 12:
			damage = 30;
			lifeMax =life = 10;				
			range = 50;
			custo= 120;
			isbuff = true;
			cadencia = 1500;
			//efeitoTiro = new FX_Tiro(x, y, 64, 32,cadencia,  "/tiros/tiro1.PNG");
			efeitoBuff = new FX_Buff(x, y, 50, 50, cadencia, "/tiros/buff3.png");
			break;
		
		}
	}

	public void Draw(Graphics2D dbg){
		if(selecionada||selecionadoNoCenario){
			dbg.setColor(cor);		
			dbg.fillRect(x-width/2, y-height/2, width, height);
			dbg.drawOval((int) (x-(range+bonusRange)), (int) (y-(range+bonusRange)), (int)(2*(range+bonusRange))  ,(int)(2*(range+bonusRange)) );
		}	
		dbg.rotate(ang, x, y);
		//		dbg.translate(-16, -16);
		if(efeitoBuff!=null){
			efeitoBuff.draw(dbg);
		}
		dbg.drawImage(imagemNoCenario, (x-imagemNoCenario.getWidth()/2),(y-(imagemNoCenario.getHeight()/2)) , null);
		if(efeitoTiro!=null)
			efeitoTiro.draw(dbg);
		if(!fixada){
			dbg.setColor(Color.BLACK);
			dbg.drawLine(x-5, y, x+5, y);
			dbg.drawLine(x, y-5, x, y+5);
		}
		
		dbg.rotate(-ang, x, y);
		
		dbg.setColor(Color.GREEN);
		dbg.fillRect((x - (imagemNoCenario.getWidth() / 2)) - 10, (y - (imagemNoCenario.getHeight() / 2))-2,
				(int) (30*life / lifeMax),
				2);
		//		dbg.drawString(""+life, x-10, y+10+(imagemNoCenario.getHeight() / 2));

	}

	public void voltaEstadoInicial(){
		x = posXInicial;
		y = posYInicial;
		selecionada = false;
		fixada = false;
	}
	float iniX = 0, iniY = 0;
	int j;
	public void Update(long diffTime){
		if(fixada){
			if(efeitoTiro!=null){
				efeitoTiro.update(diffTime);
			}
			 iniX = 0;
			 iniY = 0;
			 j= 0;
			this.timer += diffTime;	
			if(!isbuff){
				
				buff((int)diffTime);
				if (TelaJogo.liberouWave||TelaTreinamento.liberouWave){
					if(this.fixada){
						if (this.timer >= cadencia) {
							this.timer = 0;
							for (int i = 0; i < Constantes.ListaInimigos.size(); i++) {
								if ((Math.abs(Constantes.ListaInimigos.get(i).x - this.x) <= (range+bonusRange))
										&& (Math.abs(Constantes.ListaInimigos.get(i).y - this.y) <= (range+bonusRange))) {
									iniX = Constantes.ListaInimigos.get(i).x;
									iniY = Constantes.ListaInimigos.get(i).y;
									j = i;
									i = Constantes.ListaInimigos.size();
								}
							}
							if (iniX != 0 && iniY != 0) {
								Constantes.soundplayer.playTrack(Constantes.SFX_CANHAO);
								efeitoTiro.startAnimacao();
								Constantes.ListaInimigos.get(j).life -= this.damage+this.bonusAtaque;	
								float x = iniX;
								float y = iniY;
								double angbase = Math.atan2((y-this.y), x-(this.x));
								for (int i =0; i<4; i++){				
					    			double angAux = angbase;
									angAux+=Math.PI;
					    			angAux+=0.6f-(1.2f*Math.random());    			
									Faisca f = new Faisca(Color.RED,	x, y, (float)angAux, (int)( 80+(100*Math.random())), 400);
									GamePanel.listaParticulas.add(f);
								}
								if (Constantes.ListaInimigos.get(j).life <= 0) {									
									Constantes.ListaInimigos.get(j).life =0;
									TelaJogo.adicionaSangueNoBuffer((int)(x-Constantes.sangue.getWidth()/2), (int)(y-Constantes.sangue.getHeight()/2));
									Constantes.ListaInimigos.get(j).vivo = false;
								}
							}
						} else {
							//Atualiza o angulo mesmo com timer menor que a cadencia
							//Ajustar
							for (int i = 0; i < Constantes.ListaInimigos.size(); i++) {
								if ((Math.abs(Constantes.ListaInimigos.get(i).x - this.x) <= (range+bonusRange))
										&& (Math.abs(Constantes.ListaInimigos.get(i).y - this.y) <= (range+bonusRange))) {
									iniX = Constantes.ListaInimigos.get(i).x;
									iniY = Constantes.ListaInimigos.get(i).y;
									ang = Math.atan2((y-16)-iniY, (x-16)-iniX);
									j = i;
									i = Constantes.ListaInimigos.size();
								}
							}
						}
					}
				}
			}else{
				efeitoBuff.update(diffTime);
			}
		}
	}

	public void posiciona(int posX, int posY) {
		this.x = posX;
		this.y = posY;

	}


	public void mouseMove(MouseEvent e)	{


		if(selecionada){
			x = e.getX();
			y = e.getY();


			if(x+16<720 && x-16>0 && y+16<480 && y-16>0){

				int valores[] = new int[4];
				valores[0] = Constantes.listaMapas.get(Constantes.mapaAtual).mapa2[(y-height/2)/16][(x-width/2)/16];
				valores[1] = Constantes.listaMapas.get(Constantes.mapaAtual).mapa2[(y-height/2)/16][(x+width/2)/16];
				valores[2] = Constantes.listaMapas.get(Constantes.mapaAtual).mapa2[(y+height/2)/16][(x-width/2)/16];
				valores[3] = Constantes.listaMapas.get(Constantes.mapaAtual).mapa2[(y+height/2)/16][(x+width/2)/16];
				//System.out.println("valores: " + valores[0] + ", " + valores[1] + ", " + valores[2] + ", " + valores[3]);
				if(valores[0]==0 && valores[1]==0 && valores[2]==0 && valores[3]==0){

					cor = Color.GREEN;
					for (int i=0; i<TelaJogo.listasDeTorres.size(); i++){
						Tower atual = TelaJogo.listasDeTorres.get(i);
						if (!this.equals(atual) && this.testaColisaoComTorre(atual)){
							cor = Color.RED;
							i = TelaJogo.listasDeTorres.size();
						}
					}
				}else{
					cor = Color.RED;
				}
			}else{
				voltaEstadoInicial();
				cor = Color.BLUE;
			}
		}else{
			//ang = Math.atan2((y-16)-e.getY(), (x-16)-e.getX());
		}
	}


	public void mouseClik(MouseEvent e){
		if(!fixada){
			if(!selecionada){
				if(Utils.Utilidades.ColisaoRetangular(e.getX(), e.getY(), e.getX()+1, e.getY()+1, this.x-16, this.y-16, this.x+width-16, this.y+height-16)){
					selecionada= true;
				}
			}else{
				if(selecionada){
					if(cor == Color.GREEN){
						if(efeitoTiro!=null){
							efeitoTiro.setPosition(e.getX()-32, e.getY()-16);
						}else{
							efeitoBuff.setPosition(e.getX(),e.getY() );
						}
						
						fixada = true; 
						selecionada = false;
					}

				}
			}
		}else{
			if(!selecionadoNoCenario){
				if(Utils.Utilidades.ColisaoRetangular(e.getX(), e.getY(), e.getX()+1, e.getY()+1, this.x-16, this.y-16, this.x+width-16, this.y+height-16)){
					selecionadoNoCenario = true;
					cor  = Color.YELLOW;
				}else{
					selecionadoNoCenario = false;
				}
			}


		}
	}

	public boolean testaColisaoComTorre(Tower torre){
		if(torre!=this){
			if(Utilidades.ColisaoRetangular(this.x, this.y, this.x+this.width, this.y+this.height, torre.x, torre.y, torre.x+torre.width, torre.y+torre.height)){
				return true;
			}
			return false;
		}
		return true;

	}
	
	public void buff(int diffTime){
		if(GamePanel.TELA_ATIVA == GamePanel.TELA_TREINAMENTO){
			for(Tower torre:TelaTreinamento.listasDeTorresTreinamento)
				if(torre!=this){
					if(torre.isbuff){			
						if(Utilidades.colidecircular(this.x, this.y, 1, torre.x, torre.y, torre.range)){
							if(torre.lifeMax>10){

								contadorRecoverLife +=diffTime;
								if(contadorRecoverLife>delayRecoverLife){
									this.life+=this.lifeMax*0.2;								
									if(life>lifeMax){
										life = lifeMax;
									}
									contadorRecoverLife =0;
								}								
							}else{
								if(torre.damage>0){
									this.bonusAtaque =  (float) (torre.damage*0.75-(tipoDaTorre/10.0f));
									
								}else{
									this.bonusRange = (float) (this.range*0.85 -(tipoDaTorre/10.0f));

								}
							}
							
						}
					}
				}
		}else{
			for(Tower torre:TelaJogo.listasDeTorres)
				if(torre!=this){
					if(torre.isbuff){			
						if(Utilidades.colidecircular(this.x, this.y, 1, torre.x, torre.y, torre.range)){
							if(torre.lifeMax>10){
								contadorRecoverLife +=diffTime;
								if(contadorRecoverLife>delayRecoverLife){
									this.life+=torre.lifeMax*0.2;
									if(life>lifeMax){
										life = lifeMax;
									}
									contadorRecoverLife =0;
								}
								
							}else{
								if(torre.damage>0){
									this.bonusAtaque =  (float) (torre.damage*0.75-(tipoDaTorre/10.0f));
									
								}else{
									this.bonusRange = (float) (this.range*0.85 -(tipoDaTorre/10.0f));

									
								}
							}
							
						}
					}
				}
		}
		
	}

}
